package com.fany.views.rotatemenu;

import android.content.Context;
import android.graphics.*;
import android.view.MotionEvent;
import android.view.View;
import com.fany.fastsearcher.R;
import com.fany.utils.BitmapHelper;
import com.fany.utils.SystemUtils;
import com.fany.views.circlemenu.CircleArea;

import java.util.ArrayList;
import java.util.HashMap;

public class RotateMenuView extends View
{
    private RotateMenuItem touchedItem;
    private HashMap<Integer, ArrayList<RotateMenuItem>> _items = new HashMap<Integer, ArrayList<RotateMenuItem>>();
    private CircleArea _menuArea;

    private CircleArea _controllerButtonArea;
    private boolean _isControllerButtonTouching;
    private boolean _isMenuShowing = false;

    private Paint _paint = new Paint();

    public RotateMenuView(Context context)
    {
        super(context);
        int screenWidth = SystemUtils.getScreenWidth();
        int screenHeight = SystemUtils.getScreenHeight();
        _menuArea = new CircleArea();
        _menuArea.adjustArea(new PointF(0f, screenHeight), (int) (screenWidth * 0.5));

        _controllerButtonArea = new CircleArea();
        _controllerButtonArea.adjustArea(new PointF(45f, screenHeight - 100f), 45);
    }

    public RotateMenuItem addItem(String Text, int resourceId, int commandId)
    {
        RotateMenuItem item = new RotateMenuItem(_menuArea, null);
        addItem(item);
        item.setBitmap(BitmapHelper.loadBitmapResource(resourceId) );
        item.text = Text;
        item.commandId = commandId;
        adjustItemAngle();
        return item;
    }

    private void addItem(RotateMenuItem item)
    {
        int parentId = -1;
        if (item.parent != null)
        {
            parentId = item.parent.getUniqueId();
        }
        if (_items.containsKey(parentId))
        {
            ArrayList<RotateMenuItem> items = _items.get(parentId);
            items.add(item);
        }
        else
        {
            ArrayList<RotateMenuItem> items = new ArrayList<RotateMenuItem>();
            items.add(item);
            _items.put(parentId, items);
        }
    }

    public RotateMenuItem addChildItem(RotateMenuItem parent, String Text, int resourceId, int commandId)
    {
        CircleArea area = new CircleArea();
        area.adjustArea(_menuArea.centerPoint, _menuArea.radius + (parent.level + 1) * 150);
        RotateMenuItem item = new RotateMenuItem(area, parent);
        addItem(item);
        item.setBitmap(BitmapHelper.loadBitmapResource(resourceId) );
        item.text = Text;
        item.commandId = commandId;
        item.visible = false;
        adjustItemAngle();
        parent.addChild(item);
        return item;
    }

    private void adjustItemAngle()
    {
        for (ArrayList<RotateMenuItem> items : _items.values())
        {
            RotateMenuItem item = items.get(0);
            int degreeDelta = (60 + item.level * 2 * 5) / items.size();
            int angle = 285 - item.level * 5;
            for (int index = 0; index < items.size(); index++)
            {
                items.get(index).setAngle(angle);
                angle += degreeDelta;
                items.get(index).adjustItemCoordinate();
            }
        }
    }

    public void showChildItems(RotateMenuItem parent)
    {
        for (RotateMenuItem item : parent.children)
        {
            item.visible = true;
        }
        invalidate();
    }

    public void hideChildItems(RotateMenuItem parent)
    {
        for (RotateMenuItem item : parent.children)
        {
            item.visible = false;
        }
        invalidate();
    }

    public void hideChildItems(int level)
    {
        for (ArrayList<RotateMenuItem> items : _items.values())
        {
            for (int index = 0; index < items.size(); index++)
            {
                RotateMenuItem item = items.get(index);
                if (item.level == level)
                {
                    item.visible = false;
                }
            }
        }
        invalidate();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent e)
    {
        switch (e.getAction() & MotionEvent.ACTION_MASK)
        {
            case MotionEvent.ACTION_DOWN:
                _isControllerButtonTouching = _controllerButtonArea.isPointInArea(e.getX(), e.getY());
                if (_isControllerButtonTouching)
                {
                    return true;
                }
                for (ArrayList<RotateMenuItem> items : _items.values())
                {
                    for (int i = 0; i < items.size(); i++)
                    {
                        RotateMenuItem item = items.get(i);
                        if (item.visible && item.isPointInMenu(e.getX(), e.getY()))
                        {
                            item.focused = true;
                            return true;
                        }
                    }
                }
                return false;
            case MotionEvent.ACTION_UP:
                for (ArrayList<RotateMenuItem> items : _items.values())
                {
                    for (int i = 0; i < items.size(); i++)
                    {
                        RotateMenuItem item = items.get(i);
                        if (item.visible && item.focused && item.isPointInMenu(e.getX(), e.getY()))
                        {
                            performClickFocusItem(item);
                            item.focused = false;
                            return true;
                        }
                    }
                }
                if (_isControllerButtonTouching)
                {
                    if (_controllerButtonArea.isPointInArea(e.getX(), e.getY()))
                    {
                        _isMenuShowing = !_isMenuShowing;
                        invalidate();
                        return true;
                    }
                }
                return false;
        }
        return false;
    }

    private void performClickFocusItem(RotateMenuItem item)
    {
        if (!_isMenuShowing)
        {
            touchedItem = null;
            return;
        }
        if (item.focused)
        {
            touchedItem = item;
        }
    }

    private void rotateMenus()
    {

    }

    @Override
    public void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        drawController(canvas);
        if (_isMenuShowing)
        {
            for (ArrayList<RotateMenuItem> items : _items.values())
            {
                for (int index = 0; index < items.size(); index++)
                {
                    RotateMenuItem item = items.get(index);
                    if (item.visible)
                    {
                        drawItem(canvas, item);
                    }
                }
            }
        }
    }

    void drawItem(Canvas canvas, RotateMenuItem item)
    {
        Rect itemRect = item.getItemRect();
        Bitmap bitmap = item.getBitmap();
        canvas.drawBitmap(bitmap, null, itemRect, null);

        Rect rect = new Rect();
        _paint.setColor(Color.WHITE);
        _paint.setTextSize(SystemUtils.getScreenWidth() / 18);
        _paint.getTextBounds(item.text, 0, item.text.length(), rect);
        canvas.drawText(item.text, item.x - rect.width() / 2, itemRect.bottom + rect.height(), _paint);
    }

    private void drawController(Canvas canvas)
    {
        Rect itemRect = _controllerButtonArea.area;
        Bitmap bitmap =BitmapHelper.loadBitmapResource(R.drawable.composer_button) ;
        bitmap = BitmapHelper.toRoundCorner(bitmap, bitmap.getHeight());
        canvas.drawBitmap(bitmap, null, itemRect, null);
        if (!_isMenuShowing)
        {
            Rect rect = new Rect(itemRect.left + itemRect.width() / 4, itemRect.top + itemRect.height() / 4,
                    itemRect.right - itemRect.width() / 4, itemRect.bottom - itemRect.height() / 4);
            bitmap = BitmapHelper.loadBitmapResource(R.drawable.composer_icn_plus) ;
            bitmap = BitmapHelper.toRoundCorner(bitmap, bitmap.getHeight());
            canvas.drawBitmap(bitmap, null, rect, null);
        }
    }

    public RotateMenuItem getTouchedItem()
    {
        return touchedItem;
    }

    public void cleanTouchedItem()
    {
        touchedItem = null;
    }
}